package com.mall.b2c.hessian.impl;

import java.util.Date;
import java.util.Set;

import javax.annotation.Resource;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.mall.b2c.Setting;
import com.mall.b2c.bean.OrderBean;
import com.mall.b2c.bean.OrderItemBean;
import com.mall.b2c.bean.RefundBean;
import com.mall.b2c.domain.order.OrderDomain;
import com.mall.b2c.domain.order.OrderItemDomain;
import com.mall.b2c.domain.order.RefundDomain;
import com.mall.b2c.domain.order.ShippingDomain;
import com.mall.b2c.enums.OrderStatus;
import com.mall.b2c.enums.RefundStatus;
import com.mall.b2c.enums.ShipStatus;
import com.mall.b2c.hessian.TradeExtendHessian;
import com.mall.b2c.service.OrderService;
import com.mall.b2c.service.RefundService;
import com.mall.b2c.util.SettingUtils;
import com.mall.common.bean.Order;
import com.mall.common.bean.Pager;
import com.mall.common.domain.AreaDomain;
import com.mall.common.exception.NoticeException;
import com.mall.common.hessian.impl.BaseHessianImpl;
import com.mall.common.hibernate.Finder;
import com.mall.common.service.AreaService;
import com.mall.common.util.DateHelper;

@Service("b2cTradeExtendHessian")
public class TradeExtendHessianImpl extends BaseHessianImpl implements TradeExtendHessian{
	@Resource private RefundService refundService;
	@Resource private OrderService orderService;
	@Resource private AreaService areaService;

	@Override
	public String getRefundItems(String orderNo, Long memberId) {
		OrderDomain order = orderService.getOrderByMemberId(memberId, orderNo);
		if(order == null){
			throw new NoticeException("订单不存在");
		}
		if(order.getOrderStatus() == OrderStatus.waitBuyerPay){
			throw new NoticeException("订单状态不正确");
		}
		return objToJson(new OrderBean(order));
	}

	@Override
	public String getRefundPager(Long memberId, String orderNo, Date startDate,
			Date endDate, Integer refundStatus, Integer pagerNumber) {
		Finder finder = Finder.create("select new com.mall.b2c.bean.RefundBean(bean) from OrderItemDomain bean where bean.refund is not null and bean.order.member.id=:memberId");
		finder.setParam("memberId", memberId);
		if(StringUtils.isNotBlank(orderNo)){
			finder.append(" and bean.order.orderNo=:orderNo");
			finder.setParam("orderNo", orderNo);
		}
		if(startDate != null){
			finder.append(" and DATE_FORMAT(bean.refund.createDate,'%Y-%m-%d') >= :startDate");
			finder.setParam("startDate", DateHelper.date2String(startDate, "yyyy-MM-dd"));
		}
		if(endDate != null){
			finder.append(" and DATE_FORMAT(bean.refund.createDate,'%Y-%m-%d') <= :endDate");
			finder.setParam("endDate", DateHelper.date2String(endDate, "yyyy-MM-dd"));
		}
		if(refundStatus != null){
			finder.append(" and bean.refund.refundStatus =:refundStatus");
			finder.setParam("refundStatus", RefundStatus.values()[refundStatus]);
		}
		finder.setOrder(Order.desc("bean.refund.createDate"));
		Pager pager = new Pager();
		pager.setPageNumber(pagerNumber);
		pager = refundService.findByPagerForHessian(pager, finder);
		return objToJson(pager);
	}

	@Override
	public String getOrderItemInfo(Long itemId, Long memberId) {
		Finder finder = Finder.create("from OrderItemDomain bean where bean.id = :itemId and bean.order.member.id=:memberId");
		finder.setParam("itemId", itemId);
		finder.setParam("memberId", memberId);
		Object obj = finder.findUniqueByHQL();
		if(obj == null){
			throw new NoticeException("订单项不存在");
		}
		OrderItemDomain orderItem = (OrderItemDomain) obj;
		OrderDomain order = orderItem.getOrder();
		if(order.getOrderStatus() != OrderStatus.waitSellerSendGoods
			&& order.getOrderStatus() != OrderStatus.tradeFinished){
			throw new NoticeException("订单状态不正确");
		}
		
		JSONObject result = JSONObject.fromObject(new OrderItemBean(orderItem), jsonConfig);
		result.put("address", order.getAddress());
		result.put("name", order.getConsignee());
		result.put("phone", order.getContact());
		result.put("canChange", order.getOrderStatus() == OrderStatus.tradeFinished);
		
		RefundDomain refund = orderItem.getRefund();
		if(refund != null){
			if(refund.getRefundStatus() != RefundStatus.refuse){
				throw new NoticeException("该商品已提交退款申请");
			}
			result.put("isChange", refund.getIsChange());
			result.put("consignee", refund.getConsignee());
			result.put("address", refund.getAddress());
			result.put("phone", refund.getContact());
			AreaDomain area = areaService.find(refund.getAreaId());
			result.put("areaTree", area.getFullPath());
			result.put("remark", refund.getRemark());
		}else{
			AreaDomain area = areaService.find(order.getAreaId());
			result.put("areaTree", area.getFullPath());
		}
		
		return objToJson(result);
	}

	@Override
	public String applyRefund(Long itemId, Integer quantity, Boolean isChange, String consignee, 
			Long areaId, String address, String contact, String remark, Long memberId) {
		if(itemId == null){
			throw new NoticeException(isChange?"换货商品不存在":"退货商品不存在");
		}
		if(quantity == null || quantity <= 0){
			throw new NoticeException(isChange?"换货数量不正确":"退货数量不存在");
		}
		return refundService.applyRefund(itemId, quantity, isChange, consignee, areaId, address, contact, remark, memberId);
	}
	
	@Override
	public String getRefundInfo(String refundNo, Long memberId){
		RefundDomain refund = refundService.getRefund(refundNo, memberId);
		return objToJson(new RefundBean(refund));
	}

	@Override
	public void cancelRefund(String refundNo, Long memberId) {
		refundService.cancel(refundNo, memberId);
	}

	@Override
	public String getShipInfo(String orderNo, Long memberId) {
		JSONObject jObj = null;
		OrderDomain order = orderService.getOrderByMemberId(memberId, orderNo);
		if(order == null){
			throw new NoticeException("订单不存在");
		}
		
		if(order.getShipStatus() != ShipStatus.send){
			throw new NoticeException("订单未发货");
		}
		
		if(order.getDeliveryMethod() == null){
			throw new NoticeException("配送方式不存在");
		}
		
		Set<ShippingDomain> shippings = order.getShippings();
		if(shippings == null || shippings.size() == 0){
			throw new NoticeException("发货单不存在");
		}
		
		JSONArray info = new JSONArray();
		Setting setting = SettingUtils.get();
		HttpClient httpClient = new HttpClient();
		GetMethod getMethod = new GetMethod(setting.getDeliveryApi());
		NameValuePair[] nameValuePairs = new NameValuePair[6];
		nameValuePairs[0] = new NameValuePair("com", order.getDeliveryMethod().getCode());
		nameValuePairs[2] = new NameValuePair("id", setting.getDeliveryId());
		nameValuePairs[3] = new NameValuePair("secret", setting.getDeliverySecret());
		nameValuePairs[4] = new NameValuePair("encode", "utf8");
		nameValuePairs[5] = new NameValuePair("ord", "desc");
		for(ShippingDomain shipping : shippings){
			nameValuePairs[1] = new NameValuePair("nu", shipping.getLogisticsNo());
			getMethod.setQueryString(nameValuePairs);
			try {
				int status = httpClient.executeMethod(getMethod);
				if(status == HttpStatus.SC_OK){
					String json = getMethod.getResponseBodyAsString();
					jObj = JSONObject.fromObject(json);
					int errCode = jObj.getInt("errCode");
					switch(errCode){
						case 0	: jObj.put("errCode", "");break;
						case 1	: jObj.put("errCode", "单号不存在");break;
						case 2	: jObj.put("errCode", "验证码错误");break;
						case 3	: jObj.put("errCode", "链接查询服务器失败");break;
						case 6	: jObj.put("errCode", "快递单号格式错误");break;
						case 7	: jObj.put("errCode", "快递公司错误");break;
						case 10	: jObj.put("errCode", "未知错误");break;
						default	: jObj.put("errCode", "获取快递信息失败");
					}
					jObj.put("success", jObj.getInt("status") != 0);
				}else{
					jObj.put("errCode", "获取快递信息失败");
					jObj.put("success", false);
				}
				jObj.put("name", shipping.getDeliveryMethodName());
				jObj.put("nu", shipping.getLogisticsNo());
				info.add(jObj);
			} catch (Exception e) {
				
			}
		}
		
		return info.toString();
	}

	@Override
	public void refundReceive(String refundNo, Long memberId) {
		refundService.receive(refundNo, memberId);
	}

}
